﻿
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Globalization;
    using System.IO;
    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Resources;
namespace YoucaiReader.ImageTool
{
    public static class Extensions
    {
        public static void AddRange<TItem>(this Collection<TItem> target, IEnumerable<TItem> elements)
        {
            Contract.Requires<ArgumentNullException>(target != null, "Target cannot be null");
            Contract.Requires<ArgumentNullException>(elements != null, "Elements cannot be null.");
            foreach (TItem local in elements)
            {
                target.Add(local);
            }
        }

        public static void AddRange<TItem>(this ObservableCollection<TItem> target, IEnumerable<TItem> elements)
        {
            Contract.Requires<ArgumentNullException>(target != null, "Target cannot be null");
            Contract.Requires<ArgumentNullException>(elements != null, "Elements cannot be null.");
            foreach (TItem local in elements)
            {
                target.Add(local);
            }
        }

        [ContractVerification(false)]
        public static TItem[] Concat<TItem>(params TItem[][] arrays)
        {
            Contract.Requires<ArgumentNullException>(arrays != null, "Arrays cannot be null");
            int num = 0;
            for (int i = 0; i < arrays.Length; i++)
            {
                if (arrays[i] != null)
                {
                    num += arrays[i].Length;
                }
            }
            TItem[] destinationArray = new TItem[num];
            int destinationIndex = 0;
            for (int j = 0; j < arrays.Length; j++)
            {
                TItem[] sourceArray = arrays[j];
                if (sourceArray != null)
                {
                    Array.Copy(sourceArray, 0, destinationArray, destinationIndex, sourceArray.Length);
                    destinationIndex += arrays[j].Length;
                }
            }
            return destinationArray;
        }

        public static bool ContainsWildcard(this string value, string mask, bool ignoreCase)
        {
            Contract.Requires<ArgumentNullException>(value != null, "Value cannot be null.");
            return value.ContainsWildcard(mask, ignoreCase, '*');
        }

        public static bool ContainsWildcard(this string value, string mask, bool ignoreCase, char placeholder)
        {
            Contract.Requires<ArgumentNullException>(value != null, "Value cannot be null.");
            if (mask == null)
            {
                return false;
            }
            int num = 0;
            int num2 = 0;
            while ((num2 < value.Length) && (num < mask.Length))
            {
                if (mask[num] == placeholder)
                {
                    while (num2 != value.Length)
                    {
                        string str = value.Substring(num2 + 1);
                        if ((str != null) && str.ContainsWildcard(mask.Substring(num + 1), ignoreCase, placeholder))
                        {
                            return true;
                        }
                        num2++;
                    }
                    return false;
                }
                if (mask[num] != '?')
                {
                    if (!ignoreCase && (value[num2] != mask[num]))
                    {
                        return false;
                    }
                    if (ignoreCase && (char.ToLower(value[num2], CultureInfo.CurrentCulture) != char.ToLower(mask[num], CultureInfo.CurrentCulture)))
                    {
                        return false;
                    }
                }
                num++;
                num2++;
            }
            return ((num2 == value.Length) && (((num >= mask.Length) || (mask[num] == ';')) || (mask[num] == placeholder)));
        }

        public static int CreateHashCode(this IDictionary dictionary)
        {
            Contract.Requires<ArgumentNullException>(dictionary != null, "dictionary cannot be null");
            int num = 1;
            foreach (object obj2 in dictionary.Values)
            {
                if (obj2 != null)
                {
                    num ^= obj2.GetHashCode();
                }
            }
            foreach (object obj3 in dictionary.Keys)
            {
                if (obj3 != null)
                {
                    num ^= obj3.GetHashCode();
                }
            }
            return num;
        }

        public static int CreateHashCode(this IList list)
        {
            Contract.Requires<ArgumentNullException>(list != null, "List cannot be null");
            int hashCode = list.GetHashCode();
            foreach (object obj2 in list)
            {
                if (obj2 != null)
                {
                    hashCode ^= obj2.GetHashCode();
                }
            }
            return hashCode;
        }

        public static TItem[] CreateReversed<TItem>(this TItem[] array, int offset, int length)
        {
            Contract.Requires<ArgumentNullException>(array != null, "Array cannot be null");
            Contract.Requires<ArgumentException>(offset > 0, "Offset must be greater than zero.");
            Contract.Requires<ArgumentException>(length > 0, "Length must be greater than zero.");
            Contract.Requires<ArgumentException>((offset + length) < array.Length, "Range must be in size of the array.");
            TItem[] localArray = new TItem[length];
            int index = (offset + length) - 1;
            for (int i = 0; index >= offset; i++)
            {
                localArray[i] = array[index];
                index--;
            }
            return localArray;
        }

        public static TAttribute GetAttribute<TAttribute>(this MemberInfo member) where TAttribute: class
        {
            Contract.Requires<ArgumentNullException>(member != null, "Member cannot be null");
            object[] customAttributes = member.GetCustomAttributes(typeof(TAttribute), true);
            if ((customAttributes != null) && (customAttributes.Length > 0))
            {
                return (customAttributes[0] as TAttribute);
            }
            return default(TAttribute);
        }

        public static Stream GetLocalResourceStream(Uri uri)
        {
            Contract.Requires<ArgumentNullException>(uri != null, "Uri cannot be null.");
            StreamResourceInfo resourceStream = Application.GetResourceStream(uri);
            if (resourceStream == null)
            {
                Application application = Application.Current;
                if (application != null)
                {
                    string str = application.GetType().Assembly.FullName.Split(new char[] { ',' })[0];
                    string originalString = uri.OriginalString;
                    Uri uri2 = new Uri(string.Format(CultureInfo.CurrentCulture, "{0};component/{1}", new object[] { str, originalString }).Replace(@"\", "/").Replace("//", "/"), UriKind.Relative);
                    resourceStream = Application.GetResourceStream(uri2);
                }
            }
            if (resourceStream == null)
            {
                return null;
            }
            return resourceStream.Stream;
        }

        public static TValue GetOrCreateDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key) where TValue: class, new()
        {
            Contract.Requires<ArgumentNullException>(dictionary != null, "Dictionary cannot be null");
            TValue local = default(TValue);
            if (!dictionary.TryGetValue(key, out local))
            {
                dictionary[key] = local = Activator.CreateInstance<TValue>();
            }
            return local;
        }

        public static TValue GetOrCreateDefault<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, TKey key, Func<TValue> function)
        {
            Contract.Requires<ArgumentNullException>(dictionary != null, "Dictionary cannot be null");
            Contract.Requires<ArgumentNullException>(function != null, "Function cannot be null");
            TValue local = default(TValue);
            if (!dictionary.TryGetValue(key, out local))
            {
                dictionary[key] = local = function();
            }
            return local;
        }

        public static bool IsBetween<TValue>(this TValue value, TValue low, TValue high) where TValue: IComparable
        {
            return ((Comparer<TValue>.Default.Compare(low, value) <= 0) && (Comparer<TValue>.Default.Compare(high, value) >= 0));
        }

        public static bool IsEqual<TItem>(this IList<TItem> source, IList<TItem> target)
        {
            if ((target == null) && (source == null))
            {
                return true;
            }
            if ((target != null) && (source != null))
            {
                bool flag = true;
                if (source.Count == target.Count)
                {
                    for (int i = 0; (i < source.Count) && flag; i++)
                    {
                        if (!object.Equals(source[i], target[i]))
                        {
                            flag = false;
                        }
                    }
                    return flag;
                }
            }
            return false;
        }

        public static bool IsEqual<TItem>(this TItem[] source, TItem[] target)
        {
            if ((target == null) && (source == null))
            {
                return true;
            }
            if ((target != null) && (source != null))
            {
                bool flag = true;
                if (source.Length == target.Length)
                {
                    for (int i = 0; (i < source.Length) && flag; i++)
                    {
                        if (!object.Equals(source[i], target[i]))
                        {
                            flag = false;
                        }
                    }
                    return flag;
                }
            }
            return false;
        }

        public static bool IsEqual<TKey, TValue>(this IDictionary<TKey, TValue> source, IDictionary<TKey, TValue> target)
        {
            if ((target == null) && (source == null))
            {
                return true;
            }
            if ((target != null) && (source != null))
            {
                bool flag = true;
                if (source.Count == target.Count)
                {
                    foreach (KeyValuePair<TKey, TValue> pair in source)
                    {
                        if (!target.ContainsKey(pair.Key) || !object.Equals(target[pair.Key], pair.Value))
                        {
                            flag = false;
                        }
                    }
                    return flag;
                }
            }
            return false;
        }

        public static bool IsEqualUnsorted<TItem>(this IList<TItem> source, IList<TItem> target)
        {
            if ((target == null) && (source == null))
            {
                return true;
            }
            if ((target != null) && (source != null))
            {
                bool flag = true;
                if (source.Count == target.Count)
                {
                    IList<TItem> list = new List<TItem>(target);
                    for (int i = 0; (i < source.Count) && flag; i++)
                    {
                        bool flag2 = false;
                        for (int j = 0; j < list.Count; j++)
                        {
                            if (object.Equals(source[i], list[j]))
                            {
                                list.RemoveAt(j);
                                flag2 = true;
                                break;
                            }
                        }
                        flag = flag2;
                    }
                    return flag;
                }
            }
            return false;
        }

        public static TValue RemainBetween<TValue>(this TValue value, TValue low, TValue high) where TValue: IComparable
        {
            TValue local = value;
            if (Comparer<TValue>.Default.Compare(high, low) < 0)
            {
                return low;
            }
            if (Comparer<TValue>.Default.Compare(value, low) <= 0)
            {
                return low;
            }
            if (Comparer<TValue>.Default.Compare(value, high) >= 0)
            {
                local = high;
            }
            return local;
        }

        public static int Skip(this Stream stream, int count)
        {
            Contract.Requires<ArgumentNullException>(stream != null, "stream cannot be null");
            Contract.Requires<ArgumentException>(count > 0, "Count must be greater than zero.");
            byte[] buffer = new byte[count];
            return stream.Read(buffer, 0, count);
        }

        public static void Swap<TRef>(ref TRef lhs, ref TRef rhs) where TRef: class
        {
            TRef local = lhs;
            lhs = rhs;
            rhs = local;
        }

        public static T To<T>(this object target)
        {
            if (target == null)
            {
                return default(T);
            }
            return (T) target;
        }

        public static T[] ToArray<T>(this Collection<T> collection)
        {
            Contract.Requires<ArgumentNullException>(collection != null, "Collection cannot be null");
            T[] localArray = new T[collection.Count];
            for (int i = 0; i < collection.Count; i++)
            {
                localArray[i] = collection[i];
            }
            return localArray;
        }
    }
}

